<template>
	<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc' : '', (animation && !disableAnimation) ? 'animation' : '']" @touchmove.stop.prevent="clear">
		<view class="uni-popup__mask" :class="[ani, (animation && !disableAnimation) ? 'mask-ani' : '']" @click="close(true)" />
		<view class="uni-popup__wrapper" :style="{ backgroundColor: bg }" :class="[type, ani, (animation && !disableAnimation) ? 'content-ani' : '']">
			<slot />
		</view>
	</view>
</template>

<script>
	export default {
		name: 'UniPopup',
		props: {
			// 开启动画
			animation: {
				type: Boolean,
				default: true
			},
			// 弹出层类型，可选值，top: 顶部弹出层；bottom：底部弹出层；center：全屏弹出层
			type: {
				type: String,
				default: 'center'
			},
			// 蒙版点击是否关闭弹窗
			maskClick: {
				type: Boolean,
				default: true
			},
			// 背景色
			bg: {
				type: String,
				default: 'none'
			},
			// 是否启用动画（新增属性）
			disableAnimation: {
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				ani: '',
				showPopup: false,
				popupstyle: 'top',
				isDesktop: false
			}
		},
		watch: {
			type: {
				handler: function(newVal) {
					this.popupstyle = newVal
				},
				immediate: true
			}
		},
		created() {
			// this.popupstyle = this.type
			if (typeof window === 'object') {
				this.isDesktop = true
			}
		},
		methods: {
			clear() {},
			open() {
				this.showPopup = true
				if (this.disableAnimation || !this.animation) {
					// 禁用动画时直接显示
					this.ani = 'uni-' + this.type
				} else {
					// 启用动画时使用原有的动画效果
					this.$nextTick(() => {
						this.$nextTick(() => {
							this.ani = 'uni-' + this.type
						})
					})
				}
			},
			close(type) {
				if (!this.maskClick && type) return
				if (this.disableAnimation || !this.animation) {
					// 禁用动画时直接隐藏
					this.ani = ''
					this.showPopup = false
					// 触发关闭事件
					this.$emit('close')
				} else {
					// 启用动画时使用原有的动画效果
					this.ani = ''
					// 立即隐藏弹窗，无延迟
					this.showPopup = false
					// 触发关闭事件
					this.$emit('close')
				}
			}
		}
	}
</script>

<style scoped>
	.uni-popup {
		position: fixed;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		overflow: hidden;
		z-index: 9999;
		/* 确保元素在隐藏时不会出现残影 */
		will-change: transform;
		transform: translateZ(0);
	}

	.uni-popup.show {
		visibility: visible;
		opacity: 1;
	}

	.fixforpc {
		position: fixed;
	}

	.uni-popup__mask {
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		background-color: rgba(0, 0, 0, 0.4);
		opacity: 0;
	}

	.mask-ani {
		transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	}
	
	/* 禁用动画时移除遮罩层过渡效果 */
	.uni-popup:not(.animation) .uni-popup__mask {
		transition: none;
	}

	.uni-top {
		top: 0;
		left: 0;
		right: 0;
		transform: translateY(-100%);
		transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	}

	.uni-bottom {
		bottom: 0;
		left: 0;
		right: 0;
		transform: translateY(100%);
		transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	}

	.uni-center {
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		opacity: 0;
		transition: opacity 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	}
	
	/* 禁用动画时移除所有过渡效果 */
	.uni-popup:not(.animation) .uni-top,
	.uni-popup:not(.animation) .uni-bottom,
	.uni-popup:not(.animation) .uni-center {
		transition: none !important;
	}

	/* 当禁用动画时，直接应用最终状态 */
	.uni-top.uni-top,
	.uni-bottom.uni-bottom {
		transform: translateY(0);
		transition: none;
	}

	.uni-center.uni-center {
		opacity: 1;
		transition: none;
	}

	/* 仅在启用动画时应用过渡效果 */
	.uni-popup.animation .uni-top,
	.uni-popup.animation .uni-bottom {
		transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	}

	.uni-popup.animation .uni-center {
		transition: opacity 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	}

	.uni-popup.animation .uni-top.uni-top,
	.uni-popup.animation .uni-bottom.uni-bottom {
		transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	}

	.uni-popup.animation .uni-center.uni-center {
		transition: opacity 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	}
	
	/* 禁用动画时确保没有过渡效果 */
	.uni-popup:not(.animation) .uni-popup__mask,
	.uni-popup:not(.animation) .uni-popup__wrapper {
		transition: none !important;
	}

	.content-ani {
		transition: none; /* 移除原有的过渡效果，避免冲突 */
	}

	.uni-popup__wrapper {
		position: absolute;
		/* 添加硬件加速以提高动画性能 */
		transform: translateZ(0);
		will-change: transform;
		/* 确保元素在隐藏时不会出现残影 */
		backface-visibility: hidden;
		perspective: 1000px;
	}

	.uni-top,
	.uni-bottom {
		width: 100%;
	}

	.uni-top {
		top: 0;
		left: 0;
		transform: translateY(0);
	}

	.uni-bottom {
		bottom: 0;
		left: 0;
		transform: translateY(0);
	}

	.uni-center {
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		opacity: 1;
	}
</style>